package com.tarena.lbs.basic.web.service;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.basic.web.dao.repository.AdminRepository;
import com.tarena.lbs.basic.web.dao.repository.BusinessRepository;
import com.tarena.lbs.basic.web.dao.repository.StoreRepository;
import com.tarena.lbs.basic.web.thread.AuthenticationUtil;
import com.tarena.lbs.common.passport.enums.Roles;
import com.tarena.lbs.common.passport.principle.UserPrinciple;
import com.tarena.lbs.pojo.attach.param.PicUpdateParam;
import com.tarena.lbs.pojo.basic.param.StoreParam;
import com.tarena.lbs.pojo.basic.po.AdminPO;
import com.tarena.lbs.pojo.basic.po.BusinessPO;
import com.tarena.lbs.pojo.basic.po.StorePO;
import com.tarena.lbs.pojo.basic.query.AreaStoreQuery;
import com.tarena.lbs.pojo.basic.query.StoreQuery;
import com.tarena.lbs.pojo.basic.vo.StoreVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StoreService {
    @Autowired
    private StoreRepository storeRepository;
    @Autowired
    private AdminRepository adminRepository;
    @Autowired
    private BusinessRepository businessRepository;

    public PageResult<StoreVO> storePage(StoreQuery storeQuery) throws BusinessException {
        //1.拿到登录用身份
        UserPrinciple userPrinciple = getAuthentication();
        //2.判断是否是SHOP
        if (userPrinciple.getRole()==Roles.SHOP){
            //3.利用用户id查询商家id
            Integer businessId = getBusinessId(userPrinciple.getId());
            storeQuery.setBusinessId(businessId);
        }
        //4.组织分页查询 pageInfo 封装假分页,实际查的是所有
        PageResult<StoreVO> voPage = new PageResult<>();
        voPage.setPageNo(storeQuery.getPageNo());
        voPage.setPageSize(storeQuery.getPageSize());
        voPage.setTotal(100L);
        List<StorePO> pos = getStoreList(storeQuery);
        //5.判断pos有值 转化vos返回
        List<StoreVO> vos = null;
        if(CollectionUtils.isNotEmpty(pos)){
            log.info("本次查询 有商家店铺数据:{}",pos);
            vos = pos.stream().map(po->{
                StoreVO vo = new StoreVO();
                BeanUtils.copyProperties(po,vo);
                return vo;
            }).collect(Collectors.toList());
        }
        voPage.setObjects(vos);
        return voPage;
    }

    private List<StorePO> getStoreList(StoreQuery storeQuery) {
        QueryWrapper<StorePO> queryWrapper = new QueryWrapper<>();
        if (storeQuery.getBusinessId() != null) {
            queryWrapper.eq("business_id",storeQuery.getBusinessId());
        }
        return storeRepository.list(queryWrapper);
    }

    private Integer getBusinessId(Integer id) throws BusinessException {
        //查询lbs_admin详情中 的businessId字段
        //select * from lbs_admin where id=#{}
        AdminPO adminPO = adminRepository.getById(id);
        //断言 adminPO==null
        Asserts.isTrue(adminPO==null,new BusinessException("-2","登录商家账号不存在"));
        return adminPO.getBusinessId();

    }

    private UserPrinciple getAuthentication() throws BusinessException {
        //1.拿到登录用身份
        UserPrinciple userPrinciple = AuthenticationUtil.get();
        //2.断言 拿不到
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","认证解析失败"));
        return userPrinciple;
    }

    public void save(StoreParam param) throws BusinessException{
        //1.验证角色
        checkRole(Roles.SHOP);
        //2.验证当前店铺关联的商家是否存在
        checkBusinessExist(param.getBusinessId());
        //3.将param表单数据 转化成po对象
        StorePO poParam = param2po(param);
        //4.仓储层调用新增 同时增到mysql和es
        storeRepository.saveStore(poParam);
        //5.poParam新增结束 回填了业务id 用来绑定图片
        bindPictures(poParam);
    }
    @DubboReference
    private AttachApi attachApi;
    private void bindPictures(StorePO poParam) {
        //当前绑定 2个业务类型一个 店铺图片300 店铺logo 400
        List<PicUpdateParam> pictures = new ArrayList<>();
        //1.店铺logo绑定参数
        PicUpdateParam logoParam = new PicUpdateParam();
        logoParam.setBusinessId(poParam.getBusinessId());
        logoParam.setBusinessType(400);
        logoParam.setId(Integer.valueOf(poParam.getStoreLogo()));
        pictures.add(logoParam);
        //2. 店铺门店图片
        String storeImagesId = poParam.getStoreImagesId();
        String[] ids = storeImagesId.split(",");
        List<PicUpdateParam> storeImages = null;
        if(ids!=null&&ids.length>0){
            storeImages = Arrays.stream(ids).map(id->{
                PicUpdateParam param = new PicUpdateParam();
                param.setBusinessId(poParam.getId());
                param.setBusinessType(300);
                param.setId(Integer.valueOf(id));
                return param;
            }).collect(Collectors.toList());
        }
        //将店铺的门店图片 加入到 调用的接口入参
        if (CollectionUtils.isNotEmpty(storeImages)){
            pictures.addAll(storeImages);
        }
        //调用方法 远程访问图片服务
        attachApi.batchUpdateBusiness(pictures);
    }

    private StorePO param2po(StoreParam param) {
        StorePO storePO = new StorePO();
        //1.能拷贝 就直接拷贝
        BeanUtils.copyProperties(param,storePO);
        //2.挨个封装没有的属性
        //2.1 状态 时间
        storePO.setStoreStatus(0);//0启用 1禁用
        Date now = new Date();
        storePO.setCreateTime(now);
        storePO.setUpdateTime(now);
        //2.2 图片的id的格式 入参[1,2,3] 数据库字段是1,2,3
        List<String> storeImagesIds = param.getStoreImagesIds();
        if (CollectionUtils.isNotEmpty(storeImagesIds)) {
            String images = "";
            //循环 每次循环 取一个元素 拼接 使用, 判断是否不是最后一个元素
            for (int i = 0; i < storeImagesIds.size(); i++) {
                if(i==storeImagesIds.size()-1){
                    images = images+storeImagesIds.get(i);
                }else {
                    images = images+storeImagesIds.get(i)+",";
                }
            }
            storePO.setStoreImagesId(images);
        }
        //2.3 地理位置
        storePO.setStoreLatitude(param.getLatitude());
        storePO.setStoreLongitude(param.getLongitude());
        return storePO;
    }

    private void checkBusinessExist(Integer businessId) throws BusinessException {
        BusinessPO bizPO = businessRepository.getById(businessId);
        Asserts.isTrue(bizPO==null,new BusinessException("-2","商家不存在"));
    }

    private void checkRole(Roles roles) throws BusinessException {
        UserPrinciple userPrinciple = AuthenticationUtil.get();
        Asserts.isTrue(!(userPrinciple.getRole()==roles),new BusinessException("-2","用户解析认证失败"));
        Roles loginRole = userPrinciple.getRole();
        Asserts.isTrue(loginRole!=roles,new BusinessException("-2","权限不足"));
    }

    public PageResult<StoreVO> cityStores(AreaStoreQuery areaStoreQuery) throws BusinessException {
        //1.拿到用户身份 adminId
        Integer adminId = getUserId();
        //2.拿到商家id 同时判断商家账号是否存在
        Integer businessId = getBusinessId(adminId);
        //3.使用query对象 和businessId作为条件查询 店铺列表
        List<StorePO> pos = getAreaStores(areaStoreQuery,businessId);
        PageResult<StoreVO> voPage = new PageResult<>(1,10);
        voPage.setTotal(100L);
        List<StoreVO> vos = null;
        if(CollectionUtils.isNotEmpty(pos)){
            vos = pos.stream().map(po -> {
                StoreVO vo = new StoreVO();
                BeanUtils.copyProperties(po,vo);
                return vo;
            }).collect(Collectors.toList());
        }
        voPage.setObjects(vos);
        return voPage;
    }

    private List<StorePO> getAreaStores(AreaStoreQuery areaStoreQuery, Integer businessId) {
        //1.从query取出来 cityList
        List<Long> areaIds = areaStoreQuery.getCityIdList();
        //2.拼接where条件 不关心 businessId 和 cityId provinceId areaId 之间的and
        QueryWrapper<StorePO> queryWrapper = new QueryWrapper<>();
        //where business_id=#{} and(p_id in () or c_id in () or a_id in ())
        queryWrapper.eq("business_id",businessId).and(qw->{
            qw.in("province_id",areaIds).
                    or().in("city_id",areaIds).
                    or().in("area_id",areaIds);
        });
        return storeRepository.list(queryWrapper);
    }

    private Integer getUserId() throws BusinessException {
        UserPrinciple userPrinciple = AuthenticationUtil.get();
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","认证解析失败"));
        return userPrinciple.getId();
    }
}
